# 导入所需的模块和类

from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import LocalFileStore
import json
from langchain.chains import RetrievalQA
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
from langchain_community.llms import Tongyi
from langchain.agents import Tool,create_react_agent,AgentExecutor,tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain.prompts import PromptTemplate


from langchain_text_splitters import CharacterTextSplitter
from langchain_community.embeddings.dashscope import DashScopeEmbeddings


class DB:
    def __init__(self):
        # 实例化向量嵌入器
        self.embeddings = DashScopeEmbeddings()

        # 初始化缓存存储器
        self.store = LocalFileStore("./cache/")

        # 创建缓存支持的嵌入器
        self.cached_embedder = CacheBackedEmbeddings.from_bytes_store(self.embeddings, self.store,
                                                                      namespace=self.embeddings.model)

        print(self.cached_embedder)

    def add(self, chunks, key):
        # 创建向量存储
        db = FAISS.from_documents(chunks, self.cached_embedder)
        # 以索引的方式保存
        db.save_local(key)

    def search(self, ask, key):
        db = FAISS.load_local(key, self.cached_embedder, allow_dangerous_deserialization=True)
        res = db.similarity_search(ask, k=3)
        # qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=db.as_retriever(),verbose=False)
        prom = ''
        for i in res:
            print(i.page_content)
            prom += i.page_content + '\n'

        db2 = FAISS.load_local("D:\\household\\djhousehold\\tools\\movies", self.cached_embedder, allow_dangerous_deserialization=True)
        pp = db2.similarity_search(prom, k=3)
        data = ''
        for i in pp:
            data += i.page_content + '\n'
        print(data)

        return data

faissdb = DB()



llm = Tongyi()



@tool("FAQ")
def faq(input):
    """
    当用户询问关于电影问题的时候使用，返回的结果是电影的相关信息
    """
    tag = faissdb.search(input, "D:\\household\\djhousehold\\tools\\tagmovies")


    return tag


# 查询关于订单的问题
def search_order(input: str) -> str:
    print("订单号为****:", input)
    if input.strip() == "1001":
        return "订单号为1001的商品已经到达天津"
    return "订单状态：已发货，发货日期:2023-10-01"


# 查询关于推荐产品
def recommend_product(input: str) -> str:
    return "裙子"


tools = [
    Tool(name="search order", func=search_order,
         description="当用户咨询订单问题的时候使用这个工具，从用户输入中提取订单号根据订单号查询,输入只要订单号后面的码不要订单号三个字"),
    Tool(name="recommend product", func=recommend_product,
         description="当用户咨询关于推荐产品问题用这个工具回答"),
    faq
]

history = InMemoryChatMessageHistory()


template = '''Answer the following questions as best you can. You have access to the following tools:

            {tools}

            Use the following format:
            Question: the input question you must answer
            Thought: you should always think about what to do
            Action: the action to take, should be one of [{tool_names}],最多使用一次工具
            Action Input: the input to the action
            Observation: the result of the action
            ... (this Thought/Action/Action Input/Observation can repeat N times)
            Thought: I now know the final answer
            Final Answer: the final answer to the original input question

            Begin!

            Question: {input}
            Thought:{agent_scratchpad}
            Previous History:
            {history}
            '''

prompt = ChatPromptTemplate.from_template(template)

# 创建agent对象
agent = create_react_agent(llm=llm,tools=tools,prompt=prompt)
# 创建agentexecuter对象
agent_executor = AgentExecutor(agent=agent,tools=tools,verbose=False)
# invoke

def webtool(input):
    history.add_user_message(input)
    res=agent_executor.invoke({"input":input,'history':history.messages})
    history.add_ai_message(res['output'])
    if len(history.messages) > 6:
        del history.messages[:2]
    return res['output']







# with open("D:\\household\\djhousehold\\ddoc\\rag.js", "r", encoding="utf-8") as f:
#     data = f.read()
#
# print(data)
#
# template = '根据{text}生成一百个问题，不要出现```json ,```等字符'
# prompt = ChatPromptTemplate.from_template(template)
# run = prompt.format(text=data)
# res= llm.invoke(run)






# doc = TextLoader("D:\\household\\djhousehold\\ddoc\\tag.txt",encoding='utf-8').load()
# spliter = CharacterTextSplitter("\n",chunk_size=20, chunk_overlap=5)
# chunks = spliter.split_documents(doc)
#
#
# faissdb.add(chunks, 'tagmovies')


















